package com.by.auth;

import com.auth0.jwt.JWT;
import com.auth0.jwt.algorithms.Algorithm;
import com.auth0.jwt.exceptions.TokenExpiredException;
import com.auth0.jwt.interfaces.Claim;
import com.auth0.jwt.interfaces.DecodedJWT;
import com.auth0.jwt.interfaces.Verification;
import org.springframework.beans.factory.annotation.Value;


import java.util.Date;
import java.util.HashMap;
import java.util.Map;
import java.util.UUID;

/**
 * JWT生成token令牌
 */
public class TokenTemplate {
    @Value("${jwt.seccret}")
    String seccret;//密匙
    @Value("${jwt.valideTime}")
    long valideTime;//有效时间
    public final long DEFAULT_TIME = 1000 * 60 * 60 * 24;//默认有效时间
    String token;

    /**
     * 设置头部信息
     *
     * @return
     */
    Map getHeader() {
        Map map = new HashMap();
        map.put("alg", "HS256");
        map.put("typ", "JWT");
        return map;
    }

    /**
     * 过期时间
     *
     * @return
     */
    Date getValidDate() {
        long tame = System.currentTimeMillis() + getValideTime();
        Date date = new Date(tame);
        return date;
    }

    /**
     * 密匙算法
     *
     * @return
     */
    public String getSecret() {
        if (seccret == null) {
            seccret = UUID.randomUUID().toString();
        }
        return seccret;
    }

    /**
     * 设置默认时间
     *
     * @return
     */
    public long getValideTime() {
        if (valideTime == 0) {
            valideTime = DEFAULT_TIME;
        }
        return valideTime;
    }

    /**
     * 遍历map获取token信息
     * @param map
     * @return
     */
    Map<String, String> convert(Map<String, Claim> map) {
        Map<String, String> tmp = new HashMap<>();
        map.forEach((k, v) -> tmp.put(k, v.asString()));
        return tmp;
    }

    /**
     * 生成token
     *
     * @param payload
     * @return
     */
    public String generateToken(Map payload) {
        String token = JWT.create()
                .withHeader(getHeader())
                .withPayload(payload)
                .withExpiresAt(getValidDate())
                .sign(Algorithm.HMAC256(getSecret()));
        return token;
    }

    /**
     * 验证token
     */
    public ValidResult validate(String token) {
        if (token == null || "".equals(token)) {
            return new ValidResult(401, "token为空", null);
        } else {
            DecodedJWT decodedJWT = null;
            try {
                decodedJWT = JWT.require(Algorithm.HMAC256(getSecret()))
                        .build()
                        .verify(token);
            } catch (TokenExpiredException e) {
                return new ValidResult(0, "token已过期", null);
            } catch (Exception e) {
                return new ValidResult(1, "token无效", null);
            }
            Map<String, Claim> map = decodedJWT.getClaims();
            return new ValidResult(200, "验证成功", convert(map));
        }

    }

    /**
     * 刷新token
     */
    public String refreshToken(String token) {
        ValidResult result = validate(token);
        if (result.getCode() == 1) {
            return null;
        } else if (result.getCode() == 0) {
            DecodedJWT decode = JWT.decode(token);
            Map<String, Claim> map = decode.getClaims();
            return generateToken(convert(map));
        }
        Map<String, Claim> map = result.user;
        return generateToken(convert(map));
    }
}

